#include <sys/stat.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include "open_python_module.h"
#include "pre-fft.h"

using namespace std;

unsigned long get_file_size(const char *filename) {
	struct stat buf;
	if(stat(filename, &buf)<0)
	{
		return 0;
	}
	return (unsigned long)buf.st_size;
}

bool is_power_2(unsigned long num) {
	if((num & (num-1)) == 0)
		return true;
	else
		return false;
}

unsigned long floor_to_power_2(unsigned long num) {
	if(is_power_2(num))
		return num;
	else
		return (unsigned long)pow(2, floor(log(num)/log(2)));
}

unsigned long ceil_to_power_2(unsigned long num) {
	if(is_power_2(num))
		return num;
	else
		return (unsigned long)pow(2, ceil(log(num)/log(2)));
}

int add_file(const char *file_name, unsigned long dest_size) {
	PyObject *pFunc = NULL;
	PyObject *pParm = NULL;
	PyObject *pModule = NULL;
	
	if (!Py_IsInitialized())
		return -1;
	
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");
	
	// import python script
	pModule = PyImport_ImportModule("create_data");
	if(!pModule) {
		cout<<"Cant open python file!"<<endl;
		return -1;
	}
	
	// call the func "add_file"
	pFunc = PyObject_GetAttrString(pModule, "add_file");
	// create two parameters
	pParm = PyTuple_New(3);
	// set two parameters
	PyTuple_SetItem(pParm, 0, Py_BuildValue("s", file_name));
	PyTuple_SetItem(pParm, 1, Py_BuildValue("l", dest_size));
	PyTuple_SetItem(pParm, 2, Py_BuildValue("l", get_file_size(file_name)));
	// call the func
	PyEval_CallObject(pFunc, pParm);

	return 0;
}

int trunc_file(const char *file_name, unsigned long dest_size) {
	PyObject *pFunc = NULL;
	PyObject *pParm = NULL;
	PyObject *pModule = NULL;
	
	if (!Py_IsInitialized())
		return -1;
	
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('./')");
	
	// import python script
	pModule = PyImport_ImportModule("create_data");
	if(!pModule) {
		cout<<"Cant open python file!"<<endl;
		return -1;
	}
	
	// call the func "add_file"
	pFunc = PyObject_GetAttrString(pModule, "trunc_file");
	// create two parameters
	pParm = PyTuple_New(2);
	// set two parameters
	PyTuple_SetItem(pParm, 0, Py_BuildValue("s", file_name));
	PyTuple_SetItem(pParm, 1, Py_BuildValue("l", dest_size));
	// call the func
	PyEval_CallObject(pFunc, pParm);

	return 0;
}

int trunc_or_add(const char *file_name) {
	unsigned long file_size = get_file_size(file_name);
	if(is_power_2(file_size))
		return 0;
	else if(floor_to_power_2(file_size)*THRESHOLD > file_size)
		return trunc_file(file_name, floor_to_power_2(file_size));
	else
		return add_file(file_name, ceil_to_power_2(file_size));
}

void split_file(const char *file_name, char *block_size) {
	char cmd[200] = "split -b ";
	strcat(cmd, block_size);
	strcat(cmd, " ");
	strcat(cmd, file_name);
	strcat(cmd, " ");
	strcat(cmd, file_name);
	strcat(cmd, "_");
	cout<<cmd<<endl;
	system(cmd);
}
